﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SpiceNet.Models;
using SpiceNet.Simulations;

namespace SpiceNet.Circuits
{
    public partial class Circuit
    {
        /// <summary>
        /// Wrapper for CKTfndMode in cktfndm.c
        /// Find a model by name or device
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public Model FindModel(string name, Type type = null)
        {
            if (type != null)
            {
                // We know the model type, just find the model itself
                for (int i = 0; i < models[type].Count; i++)
                {
                    if (models[type][i].Name == name)
                        return models[type][i];
                }
            }
            else
            {
                // Search all
                foreach (Type t in models.Keys)
                {
                    for (int i = 0; i < models[t].Count; i++)
                    {
                        if (models[t][i].Name == name)
                            return models[t][i];
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// Find an instance by its name
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public Instance FindInstance(string name, Type type = null)
        {
            if (type != null)
            {
                // We know the model type, go through all models in this type
                foreach (Model m in models[type])
                {
                    Instance inst = m.Find(name);
                    if (inst != null)
                        return inst;
                }
            }
            else
            {
                // Search all
                foreach (Type t in models.Keys)
                {
                    foreach (Model m in models[t])
                    {
                        Instance inst = m.Find(name);
                        if (inst != null)
                            return inst;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// Get an array of all possible model types
        /// </summary>
        public Type[] ModelTypes
        {
            get
            {
                return models.Keys.ToArray();
            }
        }

        /// <summary>
        /// Get an array of all models in a model type
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public Model[] this[Type t]
        {
            get { return this.models[t].ToArray(); }
        }

        /// <summary>
        /// Get a list of all models
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public Model[] FindModels(Type type)
        {
            if (models.ContainsKey(type))
                return models[type].ToArray();
            else
                return null;
        }

        /// <summary>
        /// Break down the modes in an array
        /// </summary>
        /// <returns></returns>
        public Modes[] GetModes()
        {
            List<Modes> modes = new List<Modes>();
            foreach (var mode in Enum.GetValues(typeof(Modes)).Cast<Modes>())
            {
                if (Mode.HasFlag(mode))
                    modes.Add(mode);
            }
            return modes.ToArray();
        }
    }
}
